class GTimeLine
{
  private Calendar cal;
  private Date base;
  private int DateMode;

  Date HoverDate;
  Date defaultStartDate, StartDate;
  Date defaultEndDate, EndDate;
  int dScaleX;
  int pScale;

  GTimeLine(Date date, Date start, Date end)
  {
    defaultStartDate = start;
    defaultEndDate = end; 
    cal = Calendar.getInstance();
    this.base = date;
    cal.setTime(date);
    init();
  }

  int X, Y, W, H;
  void init()
  {
    X = 0;
    Y = APP_HEIGHT - 100;
    W = APP_WIDTH;
    H = APP_HEIGHT;

    StartDate = defaultStartDate;
    EndDate = defaultEndDate;
    HoverDate = defaultStartDate;
    dScaleX = 30;
    DateMode = Calendar.DATE;
  }

  void setDefaultStartEndDate()
  {
    this.StartDate = defaultStartDate;
    this.EndDate = defaultEndDate;
  }

  void draw()
  {
    int i = -1;

    textFont(_font, 13);
    textAlign(CENTER);
    stroke(0);

    cal.setTime(base);
    

    noStroke();

    int x, y;
    cal.add(DateMode, -pScale/dScaleX);
    while(W > dScaleX*(i-1))
    {
      cal.add(DateMode, 1);

      x = X + (dScaleX*i) + pScale%dScaleX;
      y = Y;

      fill(0x77990000);
      if(cal.getTime().compareTo(StartDate) < 0 && cal.getTime().compareTo(EndDate) > 0 || cal.getTime().compareTo(StartDate) > 0 && cal.getTime().compareTo(EndDate) < 0 )
        fill(0xFF990000);
      if(cal.getTime().compareTo(HoverDate) == 0)
        fill(0x99990000);

      if(cal.get(Calendar.DATE) == 1)
      {
        fill(0x88990022);
      }
      if((dScaleX > 15))
      {
        if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
        {
          fill(0x88990000);
        }
      }

      rect(x, y, dScaleX, H);
      fill(0xFFFFFFFF);

      if((dScaleX > 15))
      {
        textFont(_font, 13);
        text(cal.get(Calendar.DATE) , x + dScaleX/2, Y+50);
        if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
        {
          textFont(_font, 13);
          text("S" , x + dScaleX/2, Y+70);
        }
      }
      if(cal.get(Calendar.DATE) == 15)
      { 
        fill(0x44FFFFFF);
        textFont(_font, 42);
        text(cal.get(Calendar.MONTH)+1, x + dScaleX/2, Y+35);
        text(cal.get(Calendar.YEAR), x + dScaleX/2, Y+90);
      }

      i ++ ;
    }
    
    cal.add(DateMode, - (1 + (W-mouseX)/dScaleX));
  }
  
  int getX(Date date)
  {
    Date d = cal.getTime();
    cal.setTime(base);
    cal.add(Calendar.DATE,- pScale/dScaleX);
    long m1 = cal.getTimeInMillis();
    
    cal.setTime(date);
    long m2 = cal.getTimeInMillis();
    
    long days = (m2 - m1) / (24*60*60*1000);
    
    cal.setTime(d);
    
    return (int)(days*dScaleX + pScale%dScaleX);
  }

  void mousePressed()
  {
    if(mouseButton == LEFT)
    {
      StartDate = cal.getTime();
      EndDate = cal.getTime();
    }
  }

  void mouseDragged()
  {
    if(mouseButton == LEFT)
    {
      EndDate = cal.getTime();
    }  
    if(mouseButton == RIGHT)
    {
      pScale -= pmouseX - mouseX;
    }
  }

  void mouseWheel(int delta)
  {
    this.dScaleX = (this.dScaleX < 5)? 5: this.dScaleX + delta;
  }

  void mouseMoved()
  {
    HoverDate = cal.getTime();
  }

  void doubleClick()
  {
    setDefaultStartEndDate();
  }
}


